#ifndef RENDERER2D_H
#define RENDERER2D_H

#include "Renderer/orthographicCamera.h"

#include "Renderer/texture.h"

#include "Renderer/camera.h"
// #include "Renderer/EditorCamera.h"

#include "Scene/Components.h"
#include "Core/base.h"

#include "Renderer/rendererAPI.h"
#include "Renderer/framebuffer.h"

namespace CC
{

	class CC_EXPORT Renderer2D
	{
	public:
		static void Init();
		static void Shutdown();

		static void BeginScene(const Camera *camera, const glm::mat4 &transform = glm::mat4(1.0), Framebuffer* framebuffer = nullptr );
		// static void BeginScene(const EditorCamera& camera);
		// static void BeginScene(const OrthographicCamera& camera); // TODO: Remove
		static void EndScene();
		static void Flush();

		// Primitives
		static void DrawQuad(const glm::vec2 &position, const glm::vec2 &size, const glm::vec4 &color);
		static void DrawQuad(const glm::vec3 &position, const glm::vec2 &size, const glm::vec4 &color);
		static void DrawQuad(const glm::mat4 &transform, const glm::vec4 &color, int entityID = -1);
		static void DrawQuad(const glm::mat4 &transform, const glm::vec4 &color, ShaderComponent& shaderc, int entityID = -1);

		static void DrawQuad(const glm::vec3 &position, const glm::vec2 &size, Texture2D *texture, float tilingFactor = 1.0f, const glm::vec4 &tintColor = glm::vec4(1.0f));
		static void DrawQuad(const glm::mat4 &transform, Texture2D *texture, float tilingFactor = 1.0f, const glm::vec4 &tintColor = glm::vec4(1.0f), int entityID = -1);
		static void DrawQuad(const glm::mat4 &transform, Texture2D *texture, ShaderComponent& shaderc, Custom2DMaterialComponent* custom2DMaterial = nullptr, float tilingFactor = 1.0f, const glm::vec4 &tintColor = glm::vec4(1.0f), int entityID = -1);

		static void DrawSprite(const glm::mat4 &transform, Material2DComponent &src, int entityID);
		static void DrawSprite(const glm::mat4 &transform, Material2DComponent &src, ShaderComponent& shaderc, Custom2DMaterialComponent* custom2DMaterial = nullptr, int entityID = -1);

		static void DrawFont(const glm::mat4 &parentTransform, FontComponent &fontComponent, TransformComponent &transformComponent, Material2DComponent &src, int entityID = -1);

		static float GetLineWidth();
		static void SetLineWidth(float width);

		static void SetDisplayMode(DisplayModesEnum mode);

		static void OnViewportResize(uint32_t x, uint32_t y, uint32_t width, uint32_t height);

		// Stats
		struct Statistics
		{
			uint32_t DrawCalls = 0;
			uint32_t QuadCount = 0;

			uint32_t GetTotalVertexCount() const { return QuadCount * 4; }
			uint32_t GetTotalIndexCount() const { return QuadCount * 6; }
		};

        static Texture2D* GetCustomDepthAttachmentTexture2D();
        static Texture2D* GetCustomColor0AttachmentTexture2D();

		static void ResetStats();
		static Statistics GetStats();

		struct StatisEditText
		{
			glm::vec2 ClickPos;//input
			glm::ivec2 CursorMoveIndex;//input
			bool UserClick;//input
			bool UserSelect;//input
			glm::vec2 ClickPosEnd;//input Select
			glm::ivec2 CursorMoveEndIndex;//input Select

			glm::vec2 CursorDisplayPos;//output
			glm::ivec2 CursorDisplayIndex;//output x,y or column,row
			glm::ivec2 CursorDisplaySelectStartIndex;//output
			float CursorHeight;//output
        };

		static StatisEditText &GetStatisEditText();

	private:
		static void StartBatch();
		static void NextBatch();

	private:
		// static uint32_t m_ViewportWidth;
		// static uint32_t m_ViewportHeight;
		// static uint32_t m_ViewportX;
    	// static uint32_t m_ViewportY;
	};

}

#endif